package org.example.thread.testCompletableFuture;

import com.alibaba.fastjson2.JSON;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.*;
import java.util.stream.Collectors;

/**
 * @author liyishan
 * @date 2024/3/5 15:42
 * @apiNote  执行完若干线程后，执行最后一步,然后把它们的返回值组成一个List返回
 */

public class TestCompletableFuture {
    public static ThreadPoolExecutor threadPoolExecutor =
            new ThreadPoolExecutor(10,20, 0L,
                    TimeUnit.MILLISECONDS, new ArrayBlockingQueue<>(10));

    public static MonitoringThreadPoolExecutor monitoredThreadPoolExecutor =
            new MonitoringThreadPoolExecutor(10, 20, 0L,
                    TimeUnit.MILLISECONDS, new ArrayBlockingQueue<>(10));

    public static void main(String[] args) {
        //要使用线程安全的list
        List<TodoItemsListRes> todoItemsListResList = new CopyOnWriteArrayList<>();
        build(todoItemsListResList);
        Map<String, List<TodoItemsListRes>> toDoItemsMap = todoItemsListResList.stream().collect(Collectors.groupingBy(TodoItemsListRes::getBusinessId));
        try{
            List<TodoItemsListRes> result = new ArrayList<>();
            CompletableFuture<Void> allResultFuture = CompletableFuture.allOf(toDoItemsMap.values().stream()
                    .map(todoItemsListRes -> CompletableFuture.supplyAsync(() -> deal(todoItemsListRes), monitoredThreadPoolExecutor))
                    .map(future -> future.thenAccept(result::addAll))
                    .toArray(CompletableFuture[]::new));
            allResultFuture.thenRun(() -> {
                System.out.println("最后一步");
            }).join();
            System.out.println(JSON.toJSON(result));
        }catch (Exception e){
            e.printStackTrace();
        }

    }

    public static void build(List<TodoItemsListRes> todoItemsListResList){
        for (int i = 0; i < 10; i++) {
            TodoItemsListRes todoItemsListRes = new TodoItemsListRes();
            todoItemsListRes.setId(i);
            todoItemsListRes.setBusinessId("name"+i);
            todoItemsListResList.add(todoItemsListRes);
        }
    }

    public static List<TodoItemsListRes> deal(List<TodoItemsListRes> todoItemsListResList){
        for (int i = 0; i < todoItemsListResList.size(); i++) {
            TodoItemsListRes todoItemsListRes = todoItemsListResList.get(i);
            todoItemsListRes.setDealStatus(i+1);
        }
        return todoItemsListResList;
    }
}
